#ifndef __H_MVP_TRANSPORT_LCM_RECEIVER_H__
#define __H_MVP_TRANSPORT_LCM_RECEIVER_H__

#include <cstdio>

#include "transport/receiver/receiver.h"
#include "transport/lcm/lcm_proxy.h"

namespace motovis {
namespace transport {

template <typename MessageT>
class LcmReceiver : public Receiver<MessageT> {
public:
    using MessagePtr = std::shared_ptr<MessageT>;
    using MessageListener = std::function<void(const MessagePtr& msg)>;

    LcmReceiver();
    ~LcmReceiver() = default;

    void addListener(const std::string& channel_name, const MessageListener& msg_listener) override;
    void onMessage(const lcm::ReceiveBuffer *r_buf, const std::string& channel);

private:
    MessageListener listener_;
    std::shared_ptr<MessageT> msg_;
};

template <typename MessageT>
LcmReceiver<MessageT>::LcmReceiver()
{
    msg_ = std::make_shared<MessageT>();
}

template <typename MessageT>
void LcmReceiver<MessageT>::addListener(const std::string& channel_name, const MessageListener& msg_listener)
{
    listener_ = msg_listener;
    LcmProxy::Instance()->subscribe(channel_name, &LcmReceiver<MessageT>::onMessage, this);
}

template <typename MessageT>
void LcmReceiver<MessageT>::onMessage(const lcm::ReceiveBuffer *r_buf, const std::string& channel)
{
    msg_->ParseFromArray(r_buf->data, r_buf->data_size);
    listener_(msg_);
}

} // namespace transport
} // namespace motovis

#endif // __H_MVP_TRANSPORT_LCM_RECEIVER_H__
